#include <string>
#include <map>
#include <vector>

namespace Pdf
{
    template <>
    struct ObjectTraitsT<objNull>
    {
		typedef int Value;
    };

    template <>
    struct ObjectTraitsT<objInteger>
    {
        typedef __int64 Value;
    };

    template <>
    struct ObjectTraitsT<objReal>
    {
        typedef double Value;
    };

    template <>
    struct ObjectTraitsT<objKeyword>
    {
        typedef std::string Value;
    };

    template <>
    struct ObjectTraitsT<objComment>
    {
        typedef std::string Value;
    };

    template <>
    struct ObjectTraitsT<objName>
    {
        typedef std::string Value;
    };

    template <>
    struct ObjectTraitsT<objString>
    {
        typedef std::string Value;
    };

    template <>
    struct ObjectTraitsT<objDictionary>
    {
        typedef std::map< std::string, Object::Ptr >    Value;
        typedef Value::key_type                         Index;
    };

    template <>
    struct ObjectTraitsT<objArray>
    {
        typedef std::vector<Object::Ptr>                Value;
        typedef Value::size_type                        Index;
    };

    template <>
    struct ObjectTraitsT<objNames>
    {
        typedef std::vector<Object::Ptr>                Value;
        typedef Value::size_type                        Index;
    };

    template <>
    struct ObjectTraitsT<objReference>
    {
        typedef ObjectTraitsT<objInteger>::Value IntegerValue;

        struct Value
        {
            Value();
            Value(IntegerValue id, IntegerValue gen);

            bool operator == (const Value &rhs) const;
            bool operator <  (const Value &rhs) const;

            IntegerValue id;
            IntegerValue gen;
        };
    };

    // =====================================================================

    inline ObjectTraitsT<objReference>::Value::Value() : id(0), gen(0)
    {    }

    inline ObjectTraitsT<objReference>::Value::Value(IntegerValue id, IntegerValue gen) : id(id), gen(gen)
    {    }

    inline bool ObjectTraitsT<objReference>::Value::operator == (const Value &rhs) const
    {    return id == rhs.id && gen == rhs.gen;    }

    inline bool ObjectTraitsT<objReference>::Value::operator < (const Value &rhs) const
    {    return id == rhs.id ? gen < rhs.gen : id < rhs.id;    }
}